#ifndef LAYOUTSTATEMANAGER_H
#define LAYOUTSTATEMANAGER_H

#include <QObject>
#include <QHash>
#include <QString>
#include <QMutex>
#include <QDebug>
#include "unifiedfileinfo.h"  // 包含统一的LayoutMode定义

// 前向声明
struct SystemConfig;

/**
 * 统一的布局状态管理器
 * 
 * 职责：
 * 1. 管理所有文件的布局模式状态
 * 2. 提供统一的页数计算逻辑
 * 3. 管理当前活跃文件状态
 * 4. 通过信号通知状态变更
 * 
 * 设计原则：
 * - 单一数据源：所有布局状态集中存储
 * - 观察者模式：状态变更自动通知相关组件
 * - 线程安全：支持多线程访问
 * - 原子性操作：状态更新的一致性保证
 */
class LayoutStateManager : public QObject
{
    Q_OBJECT

public:
    // 使用统一的布局模式枚举（已在unifiedfileinfo.h中定义）
    // enum LayoutMode 已移除，使用全局定义

    // 单例模式访问
    static LayoutStateManager* instance();
    
    // === 布局模式管理 ===
    
    /**
     * 设置指定文件的布局模式
     * @param fileIdentity 文件的唯一标识符
     * @param mode 新的布局模式
     */
    void setFileLayoutMode(const QString& fileIdentity, ::LayoutMode mode);
    
    /**
     * 获取指定文件的布局模式
     * @param fileIdentity 文件的唯一标识符
     * @return 布局模式，如果文件不存在则返回SingleColumn
     */
    LayoutMode getFileLayoutMode(const QString& fileIdentity) const;
    
    /**
     * 批量设置多个文件的布局模式
     * @param fileIdentities 文件标识列表
     * @param mode 新的布局模式
     */
    void setBatchFileLayoutMode(const QStringList& fileIdentities, LayoutMode mode);
    
    // === 页数计算 ===
    
    /**
     * 根据文件标识和基础页数计算显示页数
     * @param fileIdentity 文件的唯一标识符
     * @param basePageCount 基础页数（原始页数或缓存页数）
     * @return 根据布局模式计算后的显示页数
     */
    int calculateDisplayPages(const QString& fileIdentity, int basePageCount) const;
    
    /**
     * 根据布局模式和基础页数计算显示页数
     * @param mode 布局模式
     * @param basePageCount 基础页数
     * @return 计算后的显示页数
     */
    static int calculateDisplayPages(LayoutMode mode, int basePageCount);
    
    // === 当前文件管理 ===
    
    /**
     * 设置当前活跃的文件
     * @param fileIdentity 文件的唯一标识符
     */
    void setCurrentFile(const QString& fileIdentity);
    
    /**
     * 获取当前活跃文件的标识
     * @return 当前文件标识，如果没有则返回空字符串
     */
    QString getCurrentFile() const;
    
    /**
     * 获取当前活跃文件的布局模式
     * @return 当前文件的布局模式
     */
    LayoutMode getCurrentLayoutMode() const;
    
    // === 工具方法 ===
    
    /**
     * 获取布局模式的文本描述
     * @param mode 布局模式
     * @return 布局模式的中文描述
     */
    static QString getLayoutModeText(LayoutMode mode);
    
    /**
     * 将旧的layoutMode值转换为新的LayoutMode枚举
     * @param oldLayoutMode 旧的布局模式值 (1=单栏, 2=双栏, 3=三栏)
     * @return 对应的LayoutMode枚举值
     */
    static LayoutMode convertFromOldLayoutMode(int oldLayoutMode);
    
    /**
     * 将LayoutMode枚举转换为旧的layoutMode值
     * @param mode LayoutMode枚举值
     * @return 对应的旧布局模式值 (1=单栏, 2=双栏, 3=三栏)
     */
    static int convertToOldLayoutMode(LayoutMode mode);

    // === 默认布局逻辑 ===

    /**
     * 根据文件路径和图片尺寸自动确定默认布局模式 (旧接口，保持兼容)
     * @param filePath 文件路径
     * @param imageWidth 图片宽度（对于图片文件）
     * @param imageHeight 图片高度（对于图片文件）
     * @return 推荐的默认布局模式
     */
    static LayoutMode getDefaultLayoutMode(const QString& filePath, int imageWidth = 0, int imageHeight = 0);

    /**
     * 重构：根据系统配置确定默认布局模式 (新接口)
     * Martin Fowler: Replace Parameter with Method Object
     * @param filePath 文件路径
     * @param systemConfig 系统配置对象
     * @param imageWidth 图片宽度（对于图片文件）
     * @param imageHeight 图片高度（对于图片文件）
     * @return 根据配置推荐的默认布局模式
     */
    static LayoutMode getDefaultLayoutModeWithConfig(const QString& filePath,
                                                   const SystemConfig& systemConfig,
                                                   int imageWidth = 0,
                                                   int imageHeight = 0);

    /**
     * 判断是否为PDF文件
     * @param filePath 文件路径
     * @return 如果是PDF文件返回true
     */
    static bool isPdfFile(const QString& filePath);

    /**
     * 判断是否为长图片
     * @param imageWidth 图片宽度
     * @param imageHeight 图片高度
     * @return 如果是长图片返回true
     */
    static bool isLongImage(int imageWidth, int imageHeight);
    
    /**
     * 清除指定文件的状态
     * @param fileIdentity 文件的唯一标识符
     */
    void removeFileState(const QString& fileIdentity);
    
    /**
     * 清除所有状态
     */
    void clearAllStates();

signals:
    /**
     * 文件布局模式发生变更时发出
     * @param fileIdentity 文件的唯一标识符
     * @param newMode 新的布局模式
     */
    void layoutModeChanged(const QString& fileIdentity, LayoutMode newMode);
    
    /**
     * 当前活跃文件发生变更时发出
     * @param fileIdentity 新的当前文件标识
     */
    void currentFileChanged(const QString& fileIdentity);
    
    /**
     * 需要刷新显示时发出
     * @param fileIdentity 需要刷新的文件标识，空字符串表示刷新所有
     */
    void displayRefreshNeeded(const QString& fileIdentity = QString());
    
    /**
     * 批量操作完成时发出
     * @param fileIdentities 受影响的文件标识列表
     * @param mode 设置的布局模式
     */
    void batchLayoutModeChanged(const QStringList& fileIdentities, LayoutMode mode);

private:
    explicit LayoutStateManager(QObject *parent = nullptr);
    ~LayoutStateManager() override;

    // === 默认布局常量 ===
    static constexpr double A4_ASPECT_RATIO = 297.0 / 210.0;  // A4纸长宽比: 1.414
    static constexpr double LONG_IMAGE_THRESHOLD = A4_ASPECT_RATIO * 1.2;  // 长图片阈值: 1.697
    
    // 禁用拷贝构造和赋值
    LayoutStateManager(const LayoutStateManager&) = delete;
    LayoutStateManager& operator=(const LayoutStateManager&) = delete;
    
    // 单例实例
    static LayoutStateManager* s_instance;
    static QMutex s_mutex;
    
    // 状态存储
    QHash<QString, LayoutMode> m_fileLayoutModes;  // 文件标识 -> 布局模式
    QString m_currentFileIdentity;                // 当前活跃文件标识
    
    // 线程安全保护
    mutable QMutex m_stateMutex;
    
    // 内部辅助方法
    void emitLayoutModeChanged(const QString& fileIdentity, LayoutMode mode);
};

#endif // LAYOUTSTATEMANAGER_H
